package org.ph.share.lock.test.thread2;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * 保护性暂停-设计模式
 *
 * @author Hush.
 * @since 2023/5/18 14:24
 */
@Slf4j
public class ProtectiveSuspension {

    /**
     * 模拟请求耗时
     *
     * @return list
     */
    public static List<Integer> request() {
        ArrayList<Integer> integers = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            int randomNum;
            try {
                randomNum = TransferMoney.getRandomNum() * 10;
                Thread.sleep(randomNum);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            integers.add(randomNum);
        }
        return integers;
    }

    public static void main(String[] args) {
        GuardedObject guardedObject = new GuardedObject();
        for (int i = 0; i < 10; i++) {
            // 消费
            new Thread(() -> {
                Object response = guardedObject.getResponse();
                log.info("获取数据：{}", response);
            }, "t1-" + i).start();
            // 生产
            new Thread(() -> {
                // 模拟获取数据，并传入守卫对象中
                guardedObject.setResponse(request());
            }, "t2-" + i).start();
        }

    }
}

/**
 * 守卫对象，实现线程之间的数据传输
 *
 * @author Hush.
 * @since 2023/5/18 14:33
 */
@Slf4j
class GuardedObject {
    private Object response;

    public synchronized Object getResponse() {
        while (response == null) {
            try {
                wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        return response;
    }

    public synchronized void setResponse(Object response) {
        this.response = response;
        notify();
    }
}